package com.wans.model.lottery.ssq.dos;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Data
@AllArgsConstructor
@NoArgsConstructor
@SuppressWarnings("all")
public class SSQUser {
    // 唯一 ID
    private String id;

    // 用户 ID
    private String userId;

    // 期号
    private String code;

    // 红球复式（逗号分隔）
    private String redBalls;

    // 蓝球复式（逗号分隔）
    private String blueBalls;

    // 中奖总金额
    private String bonusPrize;

    // 中奖等级
    private String prizeLevel;

    // 创建时间
    private LocalDateTime createTime;

    // 修改时间
    private LocalDateTime updateTime;

    // 逻辑删除标志 (0:未删, 1:删除)
    private Integer deletedFlag;



    public void calculatePrize(SSQ ssq) {
        // 1. 解析开奖号码
        Set<String> winningReds = new HashSet<>(Arrays.asList(
                ssq.getOne(), ssq.getTwo(), ssq.getThree(),
                ssq.getFour(), ssq.getFive(), ssq.getSix()
        ));
        String winningBlue = ssq.getSeven();

        // 2. 解析用户投注号码
        List<String> userReds = Arrays.asList(this.redBalls.split(","));
        List<String> userBlues = Arrays.asList(this.blueBalls.split(","));

        // 3. 计算红球匹配数量
        int redMatchCount = (int) userReds.stream()
                .filter(winningReds::contains)
                .count();

        // 4. 计算蓝球匹配数量
        boolean hasBlueMatch = userBlues.contains(winningBlue);

        // 5. 存储各奖级的中奖注数
        Map<Integer, Integer> prizeCounts = new HashMap<>();
        List<Integer> allPrizeLevels = new ArrayList<>();

        // 6. 枚举所有可能的注（C(n,6)组合）
        List<List<String>> redCombinations = generateCombinations(userReds, 6);

        for (List<String> redCombo : redCombinations) {
            for (String blue : userBlues) {
                // 计算当前注的匹配情况
                int comboRedMatch = (int) redCombo.stream()
                        .filter(winningReds::contains)
                        .count();
                boolean comboBlueMatch = blue.equals(winningBlue);

                // 确定当前注的中奖等级
                int prizeLevel = determinePrizeLevel(comboRedMatch, comboBlueMatch);
                allPrizeLevels.add(prizeLevel);

                // 仅记录中奖注（1-6级）
                if (prizeLevel >= 1 && prizeLevel <= 6) {
                    prizeCounts.put(prizeLevel, prizeCounts.getOrDefault(prizeLevel, 0) + 1);
                }
            }
        }

        // 7. 构建中奖等级字符串
        LinkedList<String> uniquePrizeLevels = allPrizeLevels.stream()
                .map(String::valueOf)
                .sorted()
                .collect(Collectors.toCollection(LinkedList::new));

        // 8. 计算总奖金
        int totalPrize = calculateTotalPrize(prizeCounts);

        // 9. 更新结果
        this.prizeLevel = String.join(",", uniquePrizeLevels);
        this.bonusPrize = String.valueOf(totalPrize);
    }

    // 生成所有可能的红球组合
    private List<List<String>> generateCombinations(List<String> elements, int k) {
        List<List<String>> result = new ArrayList<>();
        generateCombinationsHelper(elements, k, 0, new ArrayList<>(), result);
        return result;
    }

    private void generateCombinationsHelper(List<String> elements, int k, int start,
                                            List<String> current, List<List<String>> result) {
        if (current.size() == k) {
            result.add(new ArrayList<>(current));
            return;
        }
        for (int i = start; i < elements.size(); i++) {
            current.add(elements.get(i));
            generateCombinationsHelper(elements, k, i + 1, current, result);
            current.remove(current.size() - 1);
        }
    }

    // 确定单注的中奖等级
    private int determinePrizeLevel(int redMatch, boolean blueMatch) {
        if (redMatch == 6 && blueMatch) return 1;
        if (redMatch == 6) return 2;
        if (redMatch == 5 && blueMatch) return 3;
        if ((redMatch == 5) || (redMatch == 4 && blueMatch)) return 4;
        if ((redMatch == 4) || (redMatch == 3 && blueMatch)) return 5;
        if (blueMatch) return 6;
        return 7; // 未中奖
    }

    // 计算总奖金
    private int calculateTotalPrize(Map<Integer, Integer> prizeCounts) {
        int total = 0;
        if (prizeCounts.containsKey(1)) total += prizeCounts.get(1) * 5_000_000;
        if (prizeCounts.containsKey(2)) total += prizeCounts.get(2) * 200_000;
        if (prizeCounts.containsKey(3)) total += prizeCounts.get(3) * 3_000;
        if (prizeCounts.containsKey(4)) total += prizeCounts.get(4) * 200;
        if (prizeCounts.containsKey(5)) total += prizeCounts.get(5) * 10;
        if (prizeCounts.containsKey(6)) total += prizeCounts.get(6) * 5;
        return total;
    }
}